package csv;

import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

// loading csv file
public class LoadCSV {
    public static class Loader extends CSVBaseListener {
        public static final String EMPTY = "";
        // load a list of row maps that map field name to value
        List<Map<String,String >> rows = new ArrayList<>();
        // list of column names
        List<String> header;
        // build up a list of fields in current row
        List<String> currentRowFieldValues;

        public void exitHdr(CSVParser.HdrContext context) {
            header = new ArrayList<>();
            header.addAll(currentRowFieldValues);
        }

        public void enterRow(CSVParser.RowContext context) {
            currentRowFieldValues = new ArrayList<>();
        }

        public void exitRow(CSVParser.RowContext context) {
            // header row, do nothing
            if (context.getParent().getRuleIndex() == CSVParser.RULE_hdr) return;
            // it's data row
            Map<String, String> m = new LinkedHashMap<>();
            int i = 0;
            for (String v : currentRowFieldValues) {
                m.put(header.get(i), v);
                i++;
            }
            rows.add(m);
        }
        // data
        public void exitString(CSVParser.StringContext context) {
            currentRowFieldValues.add(context.STRING().getText());
        }

        public void exitText(CSVParser.TextContext context) {
            currentRowFieldValues.add(context.TEXT().getText());
        }

        public void exitEmpty(CSVParser.EmptyContext context) {
            currentRowFieldValues.add(EMPTY);
        }

    }

    public static void main(String[] args) throws IOException {
        String inputFile = null;
        if (args.length > 0) {
            inputFile = args[0];
        }
        InputStream is = System.in;
        if (inputFile != null) {
            is = new FileInputStream(inputFile);
        }
        CharStream input = CharStreams.fromStream(is);
        CSVLexer lexer = new CSVLexer(input);
        CommonTokenStream tokenStream = new CommonTokenStream(lexer);
        CSVParser parser = new CSVParser(tokenStream);
        // build a parse tree
        parser.setBuildParseTree(true);
        ParseTree tree = parser.file();

        ParseTreeWalker walker = new ParseTreeWalker();
        Loader loader = new Loader();
        walker.walk(loader, tree);
        System.out.println(loader.rows);
        System.out.println(loader.header);

    }
}
